﻿/*
* Copyright (c) 2010-2012 Tesla Engine Group
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


using Tesla.Graphics;
using Tesla.Math;
using Tesla.Xna.Util;
using XFG = Microsoft.Xna.Framework.Graphics;
using XNA = Microsoft.Xna.Framework;

namespace Tesla.Xna.Graphics {
    public sealed class XNAEffectAnnotation : IEffectAnnotation {
        private XFG.EffectAnnotation _annotation;
        private EffectParameterClass _paramClass;
        private EffectParameterType _paramType;

        /// <summary>
        /// Gets the annotation name.
        /// </summary>
        public string Name {
            get {
                return _annotation.Name;
            }
        }

        /// <summary>
        /// Gets the semantic of the annotation.
        /// </summary>
        public string Semantic {
            get {
                return _annotation.Semantic;
            }
        }

        /// <summary>
        /// Gets the parameter class of the annotation.
        /// </summary>
        public EffectParameterClass ParameterClass {
            get {
                return _paramClass;
            }
        }

        /// <summary>
        /// Gets the parameter type of the annotation.
        /// </summary>
        public EffectParameterType ParameterType {
            get {
                return _paramType;
            }
        }

        /// <summary>
        /// Gets the number of columns in the class of the annotation.
        /// </summary>
        public int ColumnCount {
            get {
                return _annotation.ColumnCount;
            }
        }

        /// <summary>
        /// Gets the number of rows in the class of the annotation.
        /// </summary>
        public int RowCount {
            get {
                return _annotation.RowCount;
            }
        }

        /// <summary>
        /// Creates a new instance of <see cref="XNAEffectAnnotation"/>.
        /// </summary>
        /// <param name="anno">The XNA annotation.</param>
        internal XNAEffectAnnotation(XFG.EffectAnnotation anno) {
            _annotation = anno;
            SetClassAndType(anno.ParameterClass, anno.ParameterType);
        }

        //Get class and type from the XNA annotation
        private void SetClassAndType(XFG.EffectParameterClass varClass, XFG.EffectParameterType varType) {
            switch(varClass) {
                case XFG.EffectParameterClass.Scalar:
                    _paramClass = EffectParameterClass.Scalar;
                    break;
                case XFG.EffectParameterClass.Vector:
                    _paramClass = EffectParameterClass.Vector;
                    break;
                case XFG.EffectParameterClass.Matrix:
                    _paramClass = EffectParameterClass.Matrix;
                    break;
                case XFG.EffectParameterClass.Object:
                    _paramClass = EffectParameterClass.Object;
                    break;
                case XFG.EffectParameterClass.Struct:
                    _paramClass = EffectParameterClass.Struct;
                    break;
            }
            switch(varType) {
                case XFG.EffectParameterType.Bool:
                    _paramType = EffectParameterType.Bool;
                    break;
                case XFG.EffectParameterType.Single:
                    _paramType = EffectParameterType.Single;
                    break;
                case XFG.EffectParameterType.Int32:
                    _paramType = EffectParameterType.Int32;
                    break;
                case XFG.EffectParameterType.String:
                    _paramType = EffectParameterType.String;
                    break;
                case XFG.EffectParameterType.Texture:
                    _paramType = EffectParameterType.Texture;
                    break;
                case XFG.EffectParameterType.Texture1D:
                    _paramType = EffectParameterType.Texture1D;
                    break;
                case XFG.EffectParameterType.Texture2D:
                    _paramType = EffectParameterType.Texture2D;
                    break;
                case XFG.EffectParameterType.Texture3D:
                    _paramType = EffectParameterType.Texture3D;
                    break;
                case XFG.EffectParameterType.TextureCube:
                    _paramType = EffectParameterType.TextureCube;
                    break;
                case XFG.EffectParameterType.Void:
                    _paramType = EffectParameterType.Void;
                    break;
            }
        }

        /// <summary>
        /// Gets the value of the annotation as a bool.
        /// </summary>
        /// <returns>
        /// The bool value
        /// </returns>
        public bool GetValueBool() {
            return _annotation.GetValueBoolean();
        }

        /// <summary>
        /// Gets the value of the annotation as an int.
        /// </summary>
        /// <returns>
        /// The int value
        /// </returns>
        public int GetValueInt() {
            return _annotation.GetValueInt32();
        }

        /// <summary>
        /// Gets the value of the annotation as a single.
        /// </summary>
        /// <returns>
        /// The single value
        /// </returns>
        public float GetValueSingle() {
            return _annotation.GetValueSingle();
        }

        /// <summary>
        /// Gets the value of the annotation as a matrix.
        /// </summary>
        /// <returns>
        /// The matrix value
        /// </returns>
        public Matrix GetValueMatrix() {
            XNA.Matrix xm = _annotation.GetValueMatrix();
            Matrix m;
            XNAHelper.ConvertMatrix(ref xm, out m);
            return m;
        }

        /// <summary>
        /// Gets the value of the annotation as a quaternion.
        /// </summary>
        /// <returns>
        /// The quaternion value
        /// </returns>
        public Quaternion GetValueQuaternion() {
            XNA.Vector4 xv = _annotation.GetValueVector4();
            Quaternion q;
            q.X = xv.X;
            q.Y = xv.Y;
            q.Z = xv.Z;
            q.W = xv.W;
            return q;
        }

        /// <summary>
        /// Gets the value of the annotation as a vector2.
        /// </summary>
        /// <returns>
        /// The vector2 value
        /// </returns>
        public Vector2 GetValueVector2() {
            XNA.Vector2 xv = _annotation.GetValueVector2();
            Vector2 v;
            v.X = xv.X;
            v.Y = xv.Y;
            return v;
        }

        /// <summary>
        /// Gets the value of the annotation as a vector3.
        /// </summary>
        /// <returns>
        /// The vector3 value
        /// </returns>
        public Vector3 GetValueVector3() {
            XNA.Vector3 xv = _annotation.GetValueVector3();
            Vector3 v;
            v.X = xv.X;
            v.Y = xv.Y;
            v.Z = xv.Z;
            return v;
        }

        /// <summary>
        /// Gets the value of the annotation as a vector4.
        /// </summary>
        /// <returns>
        /// The vector4 value
        /// </returns>
        public Vector4 GetValueVector4() {
            XNA.Vector4 xv = _annotation.GetValueVector4();
            Vector4 v;
            v.X = xv.X;
            v.Y = xv.Y;
            v.Z = xv.Z;
            v.W = xv.W;
            return v;
        }

        /// <summary>
        /// Gets the value of the annotation as a string.
        /// </summary>
        /// <returns>
        /// The string value
        /// </returns>
        public string GetValueString() {
            return _annotation.GetValueString();
        }
    }
}
